Fork me on GitHub

【redis】redis 特性

[TOC]

1. redis 特性

1.1 速度快

  • Redis的所有数据都是存放在内存中的
  • Redis是用C语言实现的, 一般来说C语言实现的程序“距离”操作系统更近, 执行速度相对会更快。
  • Redis使用了单线程架构, 预防了多线程可能产生的竞争问题。
  • 作者对于Redis源代码可以说是精打细磨, 曾经有人评价Redis是少有的集性能和优雅于一身的开源代码

1.2 基于键值对的数据结构服务器

主要提供了5种数据结构: 字符串、 哈希、 列表、 集合、 有序集合
同时在字符串的基础之上演变出了位图(Bitmaps) 和HyperLogLog两种神奇的“数据结构”

1.3 丰富的功能

  • 提供了键过期功能, 可以用来实现缓存。
  • 提供了发布订阅功能, 可以用来实现消息系统。
  • 支持Lua脚本功能, 可以利用Lua创造出新的Redis命令。
  • 提供了简单的事务功能, 能在一定程度上保证事务特性。
  • 提供了流水线(Pipeline) 功能, 这样客户端能将一批命令一次性传到Redis, 减少了网络的开销。

1.4 简单稳定

  • Redis的源码很少
  • Redis使用单线程模型
  • Redis不需要依赖于操作系统中的类库

1.5 客户端语言多

1.6 持久化

Redis提供了两种持久化方式: RDB和AOF, 即可以用两种策略将内存的数据保存到硬盘中

1.7 主从复制

Redis提供了复制功能, 实现了多个相同数据的Redis副本

1.8 高可用和分布式

Redis从2.8版本正式提供了高可用实现Redis Sentinel, 它能够保证Redis节点的故障发现和故障自动转移。
Redis从3.0版本正式提供了分布式实现Redis Cluster, 它是Redis真正的分布式实现, 提供了高可用、 读写和容量的
扩展性。

2. redis 适用场景

2.1 缓存

缓存机制几乎在所有的大型网站都有使用, 合理地使用缓存不仅可以加快数据的访问速度, 而且能够有效地降低后端数据源的压力。
Redis提供了键值过期时间设置, 并且也提供了灵活控制最大内存和内存溢出后的淘汰策略。

2.2 排行榜系统

Redis提供了列表和有序集合数据结构, 合理地使用这些数据结构可以很方便地构建各种排行榜系

2.3 计数器应用

2.4 社交网络

2.5 消息队列系统

Redis提供了发布订阅功能和阻塞队列的功能

3. 单线程架构

Redis是单线程来处理命令的, 所以一条命令从客户端达到服务端不会立刻被执行, 所有命令都会进入一个队列中, 然后逐个被执行

性能快的原因:

  • 纯内存访问, Redis将所有数据放在内存中, 内存的响应时长大约为100纳秒, 这是Redis达到每秒万级别访问的重要基础
  • 非阻塞I/O, Redis使用epoll作为I/O多路复用技术的实现, 再加上Redis自身的事件处理模型将epoll中的连接、 读写、 关闭都转换为事件, 不在网络I/O上浪费过多的时间
  • 单线程避免了线程切换和竞态产生的消耗

4. 内部编码

String字符串类型的内部编码有3种:

  • int: 8个字节的长整型。
  • embstr: 小于等于39个字节的字符串。
  • raw: 大于39个字节的字符串

Hash哈希类型的内部编码有两种:

  • ziplist(压缩列表) : 当哈希类型元素个数小于hash-max-ziplist-entries配置(默认512个) 、 同时所有值都小于hash-max-ziplist-value配置(默认64字节) 时, Redis会使用ziplist作为哈希的内部实现, ziplist使用更加紧凑的结构实现多个元素的连续存储, 所以在节省内存方面比hashtable更加优秀。
  • hashtable(哈希表) : 当哈希类型无法满足ziplist的条件时, Redis会使用hashtable作为哈希的内部实现, 因为此时ziplist的读写效率会下降, 而hashtable的读写时间复杂度为O(1) 。

List列表类型的内部编码有两种。

  • ziplist(压缩列表) : 当列表的元素个数小于list-max-ziplist-entries配置(默认512个) , 同时列表中每个元素的值都小于list-max-ziplist-value配置时(默认64字节) , Redis会选用ziplist来作为列表的内部实现来减少内存的使用。
  • linkedlist(链表) : 当列表类型无法满足ziplist的条件时, Redis会使用linkedlist作为列表的内部实现。

Set集合类型的内部编码有两种:

  • intset(整数集合) : 当集合中的元素都是整数且元素个数小于set-maxintset-entries配置(默认512个) 时, Redis会选用intset来作为集合的内部实 现, 从而减少内存的使用。
  • hashtable(哈希表) : 当集合类型无法满足intset的条件时, Redis会使 用hashtable作为集合的内部实现。

有序集合类型的内部编码有两种:

  • ziplist(压缩列表) : 当有序集合的元素个数小于zset-max-ziplistentries配置(默认128个) , 同时每个元素的值都小于zset-max-ziplist-value配 置(默认64字节) 时, Redis会用ziplist来作为有序集合的内部实现, ziplist 可以有效减少内存的使用。
  • skiplist(跳跃表) : 当ziplist条件不满足时, 有序集合会使用skiplist作 为内部实现, 因为此时ziplist的读写效率会下降。